package com.gitee.ywj1352.design.masterWorker;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author: yangwenjie.a
 * @date: 2021/6/22 10:09
 * @description:
 */
public abstract class Worker implements Runnable {

    public static final Logger LOGGER = LoggerFactory.getLogger(Worker.class);

    private ConcurrentLinkedQueue<Task> taskQueue;

    private ConcurrentHashMap<String, Object> resultMap;

    public void setTaskQueue(ConcurrentLinkedQueue<Task> taskQueue) {
        this.taskQueue = taskQueue;
    }

    public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
        this.resultMap = resultMap;
    }

    private static final Integer RETRY_TIME = 3;

    @Override
    public void run() {
        for (; ; ) {
            //do job
            Task poll = taskQueue.poll();
            if (Objects.isNull(poll))
                break;
            Object result = null;
            for (int i = 1; i < RETRY_TIME; i++) {
                try {
                    result = handle(poll);
                    break;
                } catch (Exception e) {
                    LOGGER.warn("worker 发生异常开始重试{}次", i);
                    try {
                        TimeUnit.MILLISECONDS.sleep(i * 500L);
                    } catch (InterruptedException interruptedException) {
                        // ignore
                    }
                }
            }
            // 添加结果 若有问题 则 put null
            this.resultMap.put(poll.getId().toString(), result);
        }
    }

    /**
     * 处理task任务
     *
     * @param input
     * @return result
     */
    public abstract Object handle(Task input);

}
